﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AbstraX.ServerInterfaces;
using AbstraX;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel.DomainServices.Server;
using Reflection = System.Reflection;
using E = System.Linq.Expressions;
using System.Linq.Expressions;
using System.Runtime.Serialization;
using AbstraX.XPathBuilder;
using System.Diagnostics;
using AbstraX.Templates;
using AbstraX;
using SLControlProvider.Web.Entities;
using AssemblyProvider.Web.Entities;
using AbstraX.AssemblyInterfaces;
using ControlProviders.ProviderInterfaces;
using AbstraX.TypeMappings;
using AbstraX.Contracts;
using MvvmTreeView;

namespace SLControlProvider.Web.Entities
{
    [DataContract, DebuggerDisplay("{ DebugInfo }"), ClientCodeGeneration(typeof(ControlClientInterfaceGenerator))]
    public class SLControlAssembly : IControlAssembly
    {
        protected IAssembly assembly;
        protected IBase parent;

        public SLControlAssembly()
        { 
        }
      
        public IAbstraXExtension LoadExtention(IBase baseObject, ITreeNode treeNode)
        {
            return null;
        }

        public SLControlAssembly(IAssembly assembly, IBase parent)
        {
            this.assembly = assembly;
            this.parent = parent;
        }

        [DataMember]
        public float ChildOrdinal
        {
            get
            {
                return assembly.ChildOrdinal;
            }
        }

        [DataMember]
        public string DebugInfo
        {
            get
            {
                return ID;
            }
        }

        [DataMember, Key]
        public string ID
        {
            get 
            {
                return assembly.ID;
            }
        }

        [DataMember]
        public string FolderKeyPair { get; set; }

        [DataMember]
        public string ParentID
        {
            get
            {
                return parent.ID;
            }
        }

        [DataMember]
        public IEnumerable<IAttribute> Attributes
        {
            get { throw new NotImplementedException(); }
        }

        [DataMember, Association("SLControlAssembly_SLControls", "ID", "ParentID")]
        public List<SLControl> Controls
        {
            get
            {
                List<SLControl> controls = new List<SLControl>();

                foreach (var type in assembly.Types)
                {
                    if (type.BaseTypes.Any(t => t.Name == "Control"))
                    {
                        controls.Add(new SLControl(type, this));
                    }
                }

                return controls;
            }
        }


        [DataMember]
        public IEnumerable<IElement> ChildElements
        {
            get 
            {
                var elements = this.Controls.AsQueryable().Cast<IElement>().Select(e => e);

                return elements;
            }
        }

        [DataMember]
        public IEnumerable<IOperation> Operations
        {
            get 
            {
                return null;
            }
        }

        [Include, Association("Parent_BaseType", "ID", "ParentID")]
        public BaseType DataType
        {
            get 
            {
                var type = typeof(Reflection.Assembly);

                return new BaseType
                {
                    FullyQualifiedName = type.FullName,
                    Name = type.Name,
                    ID = type.FullName
                };
            }
        }

        [DataMember]
        public string Description
        {
            get 
            {
                return string.Empty;
            }
        }

        [DataMember]
        public string Documentation
        {
            get 
            {
                return string.Empty;
            }
        }

        [DataMember]
        public string ImageURL
        {
            get 
            {
                return string.Empty;
            }
        }

        [DataMember]
        public string Name
        {
            get
            {
                return assembly.Name;
            }
        }

        public IBase Parent
        {
            get 
            {
                return parent;
            }
        }

        [DataMember]
        public bool IsContainer
        {
            get 
            {
                return true;
            }
        }

        public void ExecuteWhere(string property, object value)
        {
            assembly.ExecuteWhere(property, value);
        }

        public void ExecuteWhere(Expression expression)
        {
            assembly.ExecuteWhere(expression);
        }

        public void ExecuteWhere(XPathAxisElement element)
        {
            assembly.ExecuteWhere(element);
        }

        public void ClearPredicates()
        {
            assembly.ClearPredicates();
        }

        public IRoot Root
        {
            get
            {
                IBase baseObject = this;

                while (baseObject != null)
                {
                    baseObject = baseObject.Parent;

                    if (baseObject is IRoot)
                    {
                        return (IRoot)baseObject;
                    }
                }

                return null;
            }
        }

        [DataMember]
        public DefinitionKind Kind
        {
            get
            {
                return DefinitionKind.NotApplicable;
            }
        }

        [DataMember]
        public bool HasChildren
        {
            get 
            {
                return assembly.HasChildren;
            }
        }

        [DataMember, Include, Association("Parent_Facet", "ID", "ParentID")]
        public Facet[] Facets
        {
            get
            {
                return new Facet[0];
            }
        }

        [Exclude]
        public ContainerType AllowableContainerTypes
        {
            get { throw new NotImplementedException(); }
        }

        [Exclude]
        public ConstructType AllowableConstructTypes
        {
            get { throw new NotImplementedException(); }
        }

        [Exclude]
        public ContainerType DefaultContainerType
        {
            get { throw new NotImplementedException(); }
        }

        [Exclude]
        public ConstructType DefaultConstructType
        {
            get { throw new NotImplementedException(); }
        }
    }
}
 
